<template>
  <div>
    <el-dialog fullscreen destroy-on-close append-to-body :visible.sync="show" :before-close="cancel">
      <template #title>
        <div>
          <b>{{ formData.name }}</b> <span>{{ $t('修改自派送批次') }}</span>
        </div>
      </template>
      <div style="text-align: right; margin-bottom: 10px">
        <el-button type="info" @click="handleReset" v-hasPermi="['distribution:googleRouteBatch:resetRoute']">
          {{ $t('重置路线') }}
        </el-button>
        <el-button
          type="danger"
          @click="handleCalRoutePolyline"
          v-hasPermi="['distribution:googleRouteBatch:calRoutePolyline']"
        >
          {{ $t('计算路线优化') }}
        </el-button>
      </div>
      <div class="view-batch">
        <!-- 详情 -->
        <div class="view-batch-left">
          <div class="items">
            <!-- 当这些项目没有数据（包含数据为0）时，按钮显示灰色，有数据（数据大于0）是按钮显示蓝色 -->
            <div class="_item">
              <el-button :type="detail.packageNum > 0 ? 'primary' : 'info'" @click="handleImportPackage">
                {{ $t('导入包裹') }}
              </el-button>
              <div @click="handlePackageList">
                包裹数量:
                <b
                  :style="{
                    color: detail.packageNum > 0 ? 'blue' : '',
                  }"
                >
                  {{ detail.packageNum }}
                </b>
              </div>
            </div>
            <div class="_item">
              <el-button :type="detail.routeOptimizeNum > 0 ? 'primary' : 'info'">{{ $t('路线优化计算') }}</el-button>
              <div>
                路线优化次数: <b>{{ detail.routeOptimizeNum }}</b>
              </div>
            </div>
            <div class="_item">
              <el-button
                :type="detail.vehicleNum > 0 ? 'primary' : 'info'"
                @click="handleSetCar"
                :disabled="!$hasPermission('distribution:googleVehicle:setVehicle')"
              >
                {{ $t('设置车辆') }}
              </el-button>
              <div>
                车辆数: <b>{{ detail.vehicleNum }}</b>
              </div>
            </div>
            <div class="_item">
              <el-button :type="detail.strategyPattern ? 'primary' : 'info'">{{ $t('策略') }}</el-button>
              <!-- strategyPattern	策略模式 1-自动分配 2-平均分配 -->
              <el-select
                :disabled="!$hasPermission('distribution:googleRouteBatch:setStrategyPattern')"
                @change="handleSetStrategyPattern"
                clearable
                v-model="detail.strategyPattern"
                :placeholder="$t('策略模式')"
                style="width: 100%"
              >
                <el-option :label="$t('自动分配')" :value="1" />
                <el-option :label="$t('平均分配')" :value="2" />
              </el-select>
            </div>
            <div class="_item">
              <el-button
                :type="detail.routeNum > 0 ? 'primary' : 'info'"
                @click="handleSetRoute"
                :disabled="!$hasPermission('distribution:googleRouteBatch:getRouteBatchDetailsList')"
              >
                {{ $t('设置行程') }}
              </el-button>
              <div>
                行程数: <b>{{ detail.routeNum }}</b>
              </div>
            </div>
          </div>
          <div class="last-item">
            总时长: <b>{{ detail.totalTime }}</b> h
          </div>
        </div>
        <!-- 地图 -->
        <div class="view-batch-map" id="batchDispatchMap" ref="mapRef"></div>
      </div>
      <div slot="footer">
        <el-button @click="cancel">{{ $t('关闭') }}</el-button>
      </div>
    </el-dialog>

    <PackageList :show.sync="packageList.show" :formData="packageList.formData" @getList="getList" />
    <!-- 设置车辆 -->
    <SetCar :show.sync="setCar.show" :formData="setCar.formData" @getList="getList" />
    <SetRoute :show.sync="setRoute.show" :formData="setRoute.formData" @getList="getList" />
    <!-- 导入包裹 -->
    <ImportPackage :show.sync="importPackage.show" :formData="importPackage.formData" @getList="getList" />
    <!-- 包裹详情 -->
    <PackageDetail :show.sync="packageDetail.show" :formData="packageDetail.formData" @getList="getList" />
  </div>
</template>

<script>
import { getRouteBatchInfo, resetRoute, calRoutePolyline, setStrategyPattern } from '@/api/orderManage/batchDispatch'
import { orderPackageList } from '@/api/distribution/orderBatchs/index'
import { getStartLocation } from '@/api/orderManage/myDispatch'

import ImportPackage from '../importPackage.vue'
import PackageList from './packageList.vue'
import SetCar from './setCar.vue'
import SetRoute from './setRoute.vue'
import { v4 as uuid } from 'uuid'
import Marker from './marker.vue'
import PackageDetail from './packageDetail.vue'

import Vue from 'vue'

export default {
  components: { PackageList, SetCar, SetRoute, ImportPackage, PackageDetail },
  props: {
    /**
     * formData
     */
    formData: {
      type: Object,
      default: () => ({}),
    },
    /**
     * 控制显示隐藏
     */
    show: {
      type: Boolean,
      required: true,
      default: false,
    },
  },

  data() {
    return {
      /**
       * @description 起点marker
       * @type {google.maps.marker.AdvancedMarkerElement}
       * */
      startMarker: null,
      center: { lat: 35.6895, lng: 139.6917 },
      /**导入包裹 */
      importPackage: {
        show: false,
        formData: {},
      },
      /**包裹详情 */
      packageDetail: { show: false, formData: {} },
      packageList: { show: false, formData: {} },
      setCar: { show: false, formData: {} },
      setRoute: { show: false, formData: {} },
      map: null,
      detail: {
        strategyPattern: '',
      },
      vehicles: [],
      lineColors: ['#32CCBC', '#F6416C', '#28C76F', '#ff7003', '#9708CC'],
      lineColorsIndex: 0,
      markers: [],
      polylines: [],
    }
  },
  computed: {},
  watch: {
    show: function (newValue) {
      if (newValue) {
        this.reset()
        this.getList()
      }
    },
  },
  methods: {
    handleSetStrategyPattern(strategyPattern) {
      const data = {
        id: this.formData.id,
        strategyPattern,
      }
      setStrategyPattern(data).then((res) => {
        const { code, data, msg } = res
        if (code === 200) {
          this.$message({ type: 'success', message: msg })
          this.getList()
        }
      })
    },
    /**设置起点marker */
    async setStartMarker() {
      const { AdvancedMarkerElement } = await google.maps.importLibrary('marker')
      const img = document.createElement('img')
      img.src = require('@/assets/images/startPoint.png')
      img.className = 'google-start-marker'
      // if (this.startMarker) return
      getStartLocation().then((res) => {
        const { latitude, longitude } = res
        const position = { lat: latitude, lng: longitude }
        this.startMarker = new AdvancedMarkerElement({
          map: this.map,
          position,
          content: img,
        })
      })
    },
    getList() {
      getRouteBatchInfo({ batchId: this.formData.id }).then((res) => {
        this.detail = { ...res.data }
        // 没有路线的时候不需要显示地图
        if (!res.data.routeList) {
          this.resetMap()
          return
        }
        this.initMap(res.data.routeList)
      })
    },
    reset() {
      this.vehicles = []
      this.lineColorsIndex = 0
    },
    /**创建组件挂载 */
    createComponent(vueComponents, propsData) {
      // 创建一个临时的 Vue 实例来渲染组件
      const Component = Vue.extend(vueComponents)
      const instance = new Component({
        propsData: { ...propsData },
      })
      instance.$mount()
      return instance
    },
    /**重置路线 */
    handleReset() {
      this.$confirm(this.$t('确认重置?'), this.$t('提示'), {
        type: 'warning',
      }).then(() => {
        const data = {
          id: this.formData.id,
        }
        resetRoute(data).then((res) => {
          const { code, data, msg } = res
          if (code === 200) {
            this.$message({ type: 'success', message: msg })
            this.getList()
          }
        })
      })
    },
    /**计算路线优化 */
    handleCalRoutePolyline() {
      this.$confirm(this.$t('确认计算路线优化?'), this.$t('提示'), {
        type: 'warning',
      }).then(() => {
        const loading = this.$loading({
          lock: true,
          text: 'Loading',
          spinner: 'el-icon-loading',
          background: 'rgba(0, 0, 0, 0.5)',
        })
        const data = {
          routeBatchId: this.formData.id,
          strategyPattern: this.detail.strategyPattern,
          // vehicles: this.vehicles.map((i) => {
          //   const { id, displayName, loadWeight } = i
          //   return {
          //     id,
          //     displayName,
          //     loadLimits: +loadWeight,
          //   }
          // }),
        }
        calRoutePolyline(data)
          .then((res) => {
            const { code, data, msg } = res
            if (code === 200) {
              this.$message({ type: 'success', message: msg })
              this.getList()
            }
          })
          .catch((err) => err)
          .finally(() => {
            loading.close()
          })
      })
    },
    /**导入包裹 */
    handleImportPackage() {
      this.importPackage.formData = { id: this.formData.id }
      this.importPackage.show = true
    },
    handlePackageList() {
      let flag = this.$hasPermission('distribution:googleRouteBatch:getGoogleRouteShipmentsList')
      if (!flag) return
      this.packageList.formData = { ...this.formData }
      this.packageList.show = true
    },
    handleSetCar() {
      this.setCar.formData = { ...this.formData }
      this.setCar.show = true
    },
    handleSetRoute() {
      this.setRoute.formData = { ...this.formData }
      this.setRoute.show = true
    },
    async addMarker(params) {
      const { position, index, lineColor, polyline, item } = params
      const { AdvancedMarkerElement } = await google.maps.importLibrary('marker')
      /** @type {google.maps.marker.AdvancedMarkerElement}*/
      const marker = await new AdvancedMarkerElement({
        map: this.map,
        position,
        content: this.createComponent(Marker, { lineColor, index, title: index }).$el,
      })
      marker.addListener('click', () => {
        orderPackageList({ packageNo: item.packageNo, routeId: item.routeId }).then((res) => {
          const { code, data, msg } = res
          if (code === 200) {
            this.packageDetail.formData = { ...res.rows[0], item }
            this.packageDetail.show = true
          }
        })
      })

      this.polylines.push(polyline)
      this.markers.push(marker)
    },
    resetMap() {
      // 要清空谷歌地图上的所有线（Polyline）和标记（Marker）
      this.markers.map((m) => m.setMap(null))
      this.markers = []
      this.polylines.map((p) => p.setMap(null))
      this.polylines = []
      this.lineColorsIndex = 0
    },
    initMap(routeList) {
      // 刷新的时候直接渲染
      if (this.map) {
        this.resetMap()
        this.drawLines(routeList)
      } else {
        this.$nextTick(() => {
          this.map = new google.maps.Map(this.$refs['mapRef'], {
            zoom: 10,
            center: this.center,
            mapId: 'batchDispatch_map',
          })
          // 确保地图加载完成后再添加路径
          google.maps.event.addListenerOnce(this.map, 'idle', () => {
            this.drawLines(routeList)
            this.setStartMarker(routeList[0])
          })
        })
      }
    },
    /**重复设置颜色 */
    getColor() {
      let color
      if (this.lineColorsIndex < this.lineColors.length - 1) {
        color = this.lineColors[this.lineColorsIndex]
        this.lineColorsIndex += 1
      } else {
        this.lineColorsIndex = 0
        color = this.lineColors[this.lineColorsIndex]
        this.lineColorsIndex += 1
      }
      return color
    },
    /**绘制线路图 */
    async drawLines(routeList) {
      if (!routeList) return
      const {
        encoding: { decodePath },
      } = await google.maps.importLibrary('geometry')
      let self = this
      routeList.map((r, idx) => {
        /**@type {Array} */
        const pathArr = r.map((i) => {
          return {
            ...i,
            path: decodePath(i.routePolyLine),
          }
        })
        // console.log(`pathArr ==>`,pathArr);
        const strokeColor = this.getColor()
        pathArr.map((item, index) => {
          const routePolylineIndex = item.routePolylineIndex
          const polyline = new google.maps.Polyline({
            path: item.path,
            geodesic: true,
            strokeColor,
            strokeOpacity: 1.0,
            strokeWeight: 5,
          })
          polyline.setMap(this.map)
          polyline.addListener('mouseover', function () {
            this.setOptions({
              strokeColor: '#000',
              zIndex: pathArr.length,
            })
          })
          polyline.addListener('mouseout', function () {
            this.setOptions({
              strokeColor,
              zIndex: routePolylineIndex,
            })
          })
          // 添加marker
          this.addMarker({
            polyline,
            position: item.path[item.path.length - 1],
            index: `${idx + 1}-${item.routePolyLineIndex}`,
            lineColor: strokeColor,
            item: item,
          })
        })
      })
      this.setStartMarker()
    },
    /**设置中心点位 */
    setMapCenter(param = {}) {
      const { lat = 35.6895, lng = 139.6917 } = param
      this.map.setCenter({ lat, lng })
    },

    cancel() {
      this.map = null // 将地图对象设置为null，释放内存
      this.$emit('update:show', false)
    },
  },
}
</script>
<style scoped lang="scss">
.view-batch {
  display: flex;
  height: 75vh;
  $border: 1px solid #ccc;
  &-left {
    width: 270px;
    border: $border;
    border-right: 0;
    display: flex;
    flex-direction: column;
    justify-content: space-between;
    display: flex;
    flex-direction: column;
    justify-content: space-between;
    .items {
      ._item {
        cursor: pointer;
        margin-bottom: 35px;
        button {
          width: 100%;
        }
        div {
          text-align: center;
          padding: 10px;
          border-bottom: $border;
        }
      }
    }
    .last-item {
      text-align: center;
      padding: 10px;
    }
  }
  &-map {
    flex: 1;
    border: $border;
  }
}
</style>
